package com.tuzhi.util;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class CopyTzUtil {


    /**
     * 复制对象属性到另一个对象属性中，默认包含父属性和忽略修饰符
     * @param srcObj
     * @param tagObj
     */
    public static void copyObj(Object srcObj, Object tagObj) {
        copyObj(srcObj, tagObj, true, true, null);
    }

    /**
     * 复制对象属性到另一个对象属性中
     * @param srcObj    复制原对象，不能空
     * @param tagObj    目标对象，不能空
     * @param allFields 是否包括父类属性，true为包括
     * @param ignoreModifier    是否忽略属性的修饰符，true为忽略，false只处理public的属性
     * @param excludeSet        排除的属性名的集合
     */
    public static void copyObj(Object srcObj, Object tagObj, boolean allFields, boolean ignoreModifier, Set<String> excludeSet) {
        if (srcObj == null) {
            throw new IllegalArgumentException("srcObj为空！");
        }
        if (tagObj == null) {
            throw new IllegalArgumentException("tagObj为空！");
        }

        Field[] srcFields = srcObj.getClass().getDeclaredFields();
        if (allFields) {
            //包括父类的属性，去除掉父类和子类相同的属性
            Map<String, Field> tmpMap = new HashMap<>();
            for (Class<?> superClass = srcObj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
                //set.addAll(Arrays.asList(superClass.getDeclaredFields()));
                Field[] tmpFields = superClass.getDeclaredFields();
                if (tmpFields != null && tmpFields.length > 0) {
                    for (Field tmpField : tmpFields) {
                        if (!tmpMap.containsKey(tmpField.getName())) {
                            tmpMap.put(tmpField.getName(), tmpField);
                        }
                    }
                }
            }
            srcFields = tmpMap.values().toArray(srcFields);
        }

        for (Field srcField : srcFields) {
            if (excludeSet != null && excludeSet.contains(srcField.getName())) {
                System.out.println("排除" + srcField.getName());
                continue;
            }
            boolean accessible = false;
            if (ignoreModifier) {
                accessible = true;
            } else {
                if (!Modifier.isPublic(srcField.getModifiers())) {
                    System.out.println("非public修饰符,跳过" + srcField.getName());
                    continue;
                }
            }
            srcField.setAccessible(accessible);

            try {
                ReflectionTzUtil.setFieldValue4Exception(tagObj, srcField.getName(), srcField.get(srcObj));
            } catch (Exception e) {
//                System.out.println("设置值出错" + srcField.getName());
//                System.out.println(ExceptionUtils.getStackTrace(e));
            }

        }


    }

    public static void main(String[] args) {

//        C c = new C();
//        c.setD(11.1);
//
//        SA sa = new SA();
//        sa.setS("s1");
//        sa.setSa("sa1");
//        sa.setB(true);
//        sa.setC(c);
//
//        System.out.println(sa);
//        A a = new A();
//        System.out.println(a);
//        copyObj(sa, a, true, true, null);
//        System.out.println(a);
//
//        SA sa1 = new SA();
//        copyObj(sa, sa1);
//        System.out.println(sa1);

    }


}
